package com.kingbook.core.result;

import com.alibaba.fastjson.JSONArray;
import com.kingbook.common.utils.StringUtils;
import com.kingbook.core.enums.ResultCode;

import java.beans.Transient;
import java.io.Serializable;
import java.util.Collection;

import static com.kingbook.core.enums.ResultCode.FAILED;
import static com.kingbook.core.enums.ResultCode.SUCCESS;

/**
 * @Author: Bucky
 * @Date: 2019/1/2
 * @Version 1.0
 */
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 6240041458084284609L;

    protected ResultCode code;

    protected int count;

    protected String msg;

    protected T data;

    public Result() {
    }

    protected Result(ResultCode code, String msg, int count, T data) {
        this.code = code;
        this.msg = msg;
        this.count = count;
        this.data = data;
    }

    public static <T> Result<T> failed() {
        return failed(FAILED.toString());
    }

    public static <T> Result<T> failed(String msg) {
        return failed(FAILED, msg);
    }

    public static <T> Result<T> failed(ResultCode code, String msg) {
        return new Result<T>(code, msg, 0, null);
    }

    public static <T> Result<T> failed(ResultCode code, String msg, T t) {
        return new Result<T>(code, msg, 0, t);
    }

    public static <T> Result<T> success() {
        return success(SUCCESS.toString());
    }

    public static <T> Result<T> success(int count) {
        return new Result<T>(SUCCESS, "", count, null);
    }

    public static <T> Result<T> success(String msg) {
        return success(msg, null);
    }

    public static <T> Result<T> success(String msg, T t) {
        if (t != null) {
            if (JSONArray.class.isInstance(t)) {
                return new Result<T>(SUCCESS, msg, ((JSONArray) t).size(), t);
            } else if (Collection.class.isInstance(t)) {
                return new Result<T>(SUCCESS, msg, ((Collection<?>) t).size(), t);
            } else if (t.getClass().isArray()) {
                return new Result<T>(SUCCESS, msg, ((Object[]) t).length, t);
            }
        }
        return new Result<T>(SUCCESS, msg, 0, null);
    }


    public int getCode() {
        return code.value;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public String getMsg() {
        return StringUtils.isEmpty(msg) ? code.name() : msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Transient
    public boolean isSuccess() {
        return this.code == ResultCode.SUCCESS;
    }

    @Transient
    public ResultCode getEnumCode() {
        return code;
    }
}
